package com.wctj.api.business.huifu.service.handler;

import com.alibaba.fastjson.JSON;
import com.wctj.api.base.Result;
import com.wctj.api.base.enums.ApiCode;
import com.wctj.api.base.enums.EventTypeEnums;
import com.wctj.api.base.exception.CustomException;
import com.wctj.api.base.utils.HttpClientUtil;
import com.wctj.api.base.utils.JsonUtils;
import com.wctj.api.base.utils.TimeUtils;
import com.wctj.api.business.common.component.AsyncTransactionalEvent;
import com.wctj.api.business.common.dto.DdwxPaymentMessageInfoDTO;
import com.wctj.api.business.common.dto.DdwxPaymentRecordDTO;
import com.wctj.api.business.common.service.DdwxPaymentRecordService;
import com.wctj.api.business.common.service.handler.HuiFuAbstractEventTypeResponse;
import com.wctj.api.business.huifu.dto.HuiFuNoticeParamsData;
import com.wctj.api.business.huifu.dto.HuiFuRequestNoticeParams;
import com.wctj.api.business.huifu.enums.HuiFuPayStatusEnums;
import com.wctj.api.infra.common.bean.NoticeParams;
import com.wctj.api.infra.web.support.HttpRequestNoticeParams;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 汇付天下-Adapay-payment 支付回调响应模式处理
 */
@Slf4j
@Service
public class HuiFuPaymentEventTypeResponse extends HuiFuAbstractEventTypeResponse {
    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private DdwxPaymentRecordService ddwxPaymentRecordService;

    @Override
    public String businessHandle(HttpRequestNoticeParams requestNoticeParam) {
        NoticeParams noticeParams = this.getNoticeParams(requestNoticeParam);
        // 异步事件处理
        applicationContext.publishEvent(new AsyncTransactionalEvent(this, "eventTypePayment:" + Thread.currentThread().getId(),
                () -> {
                    try {
                        payBack(noticeParams,null);
                    } catch (Exception e) {
                        log.error("支付分发失败", e);
                    }
                }));
        return noticeParams.getBodyStr();
    }

    @Override
    public String businessHandle(NoticeParams noticeParams) {
        return "";
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void payBack(NoticeParams noticeParams, String payOrderNum) {
        String bodyStr = StringUtils.isBlank(noticeParams.getBodyStr()) ? JsonUtils.toJson(noticeParams.getBody()) : noticeParams.getBodyStr();
        log.info("Adapay payemnt payBack param：{}", bodyStr);
        HuiFuRequestNoticeParams noticeDto = JSON.parseObject(bodyStr, HuiFuRequestNoticeParams.class);
        HuiFuNoticeParamsData data = JsonUtils.readFromString(noticeDto.getData(), HuiFuNoticeParamsData.class);
        // 开发平台创建的支付订单编号
        String payOrderNumber = data.getOrderNo();
        DdwxPaymentRecordDTO recordDTO = ddwxPaymentRecordService.findByPayOrderNumber(payOrderNumber);
        if (Objects.isNull(recordDTO)){
            throw new CustomException(ApiCode.PAY_ORDER_NOT_EXIST);
        }
        // 回传业务支付订单编号
        noticeDto.setBizOrderNo(recordDTO.getBizOrderNum());
        int status = HuiFuPayStatusEnums.of(data.getStatus()).getCode();
        // 更新支付状态
        ddwxPaymentRecordService.updateById(new DdwxPaymentRecordDTO(recordDTO.getId(), status, TimeUtils.getNow()));
        // {@link HuiFuPayStatusEnums}
        int pushStatus = 0;
        // 推送时间
        LocalDateTime pushTime = TimeUtils.getNow();
        String noticeBodyJsonStr = JsonUtils.toJson(new Result(ApiCode.ADAPAY,noticeDto));
        // 查通知业务线的地址
        DdwxPaymentMessageInfoDTO msgDto = ddwxPaymentMessageInfoService.findByPayOrderNumber(recordDTO.getPayOrderNum());
        String notifyUrl = msgDto.getNotifyUrl();
        try {
            // 发送通知推送
            String resultMsg = HttpClientUtil.postJSON(notifyUrl,null,noticeBodyJsonStr);
            // 转义结果
            Result rts = JSON.parseObject(resultMsg,Result.class);
            if (Objects.nonNull(rts) && rts.getCode() == ApiCode.OK.getCode().intValue()) {
                pushStatus = HuiFuPayStatusEnums.succeeded.getCode();
            }else{
                pushStatus = HuiFuPayStatusEnums.failed.getCode();
            }
        }catch (Exception ex){
            log.error("Adapay支付回调异常",ex);
            pushStatus = HuiFuPayStatusEnums.failed.getCode();
        }finally {
            updateMessage(payOrderNumber,status, pushStatus, pushTime, noticeBodyJsonStr);
        }
        log.info("Adapay payemnt payBack result：{}", bodyStr);
    }


    @Override
    public String getEventType() {
        return EventTypeEnums.payment.getType();
    }

}
